

#include <wchar.h>
#include "Parser.h"
#include "Scanner.h"




void Parser::SynErr(int n) {
	if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
	errDist = 0;
}

void Parser::SemErr(const wchar_t* msg) {
	if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
	errDist = 0;
}

void Parser::Get() {
	for (;;) {
		t = la;
		la = scanner->Scan();
		if (la->kind <= maxT) { ++errDist; break; }

		if (dummyToken != t) {
			dummyToken->kind = t->kind;
			dummyToken->pos = t->pos;
			dummyToken->col = t->col;
			dummyToken->line = t->line;
			dummyToken->next = NULL;
			coco_string_delete(dummyToken->val);
			dummyToken->val = coco_string_create(t->val);
			t = dummyToken;
		}
		la = t;
	}
}

void Parser::Expect(int n) {
	if (la->kind==n) Get(); else { SynErr(n); }
}

void Parser::ExpectWeak(int n, int follow) {
	if (la->kind == n) Get();
	else {
		SynErr(n);
		while (!StartOf(follow)) Get();
	}
}

bool Parser::WeakSeparator(int n, int syFol, int repFol) {
	if (la->kind == n) {Get(); return true;}
	else if (StartOf(repFol)) {return false;}
	else {
		SynErr(n);
		while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
			Get();
		}
		return StartOf(syFol);
	}
}

void Parser::Sql() {
		flagg=0;
		if (StartOf(1)) {
			Modify_data();
		} else if (la->kind == 6) {
			Define_data();
		} else SynErr(39);
}

void Parser::Modify_data() {
		if (la->kind == 23) {
			Select_command();
		} else if (la->kind == 32) {
			Insert_command();
		} else if (la->kind == 29) {
			Update_command();
		} else if (la->kind == 35) {
			Delete_command();
		} else if (la->kind == 22) {
			Drop_command();
		} else SynErr(40);
}

void Parser::Define_data() {
		vector<ckval> a;
		string table; 
		Create_command(a,table);
		Expect(5);
		if(errors->count==0){
		_create(table,a);flagg=1;}
}

void Parser::Create_command(vector<ckval> &a, string &table ) {
		Expect(6);
		Expect(7);
		str(table);
		Expect(8);
		Name_type_pair(a);
		while (la->kind == 9) {
			Get();
			Name_type_pair(a);
		}
		Expect(10);
}

void Parser::Select_command() {
		vector<string> columnlist;
		vector<string> a,b,c;int count=0;
		 string table,temp;vector<int> condition;
		Expect(23);
		if (la->kind == 24 || la->kind == 25) {
			if (la->kind == 24) {
				Get();
			} else {
				Get();
			}
		}
		if (la->kind == 1) {
			str_list(columnlist);
			while (la->kind == 9) {
				Get();
				str_list(columnlist);
			}
		} else if (la->kind == 26) {
			Get();
			columnlist.push_back("*");
		} else SynErr(41);
		Expect(27);
		str(table);
		if (la->kind == 28) {
			Get();
			Condition(condition,a,b,c,count);
		}
		Expect(5);
		if(errors->count==0){
		_select(table,columnlist,condition,a,b,c);flagg=1;}
}

void Parser::Insert_command() {
		string table;
		vector<string> columns,values;
		Expect(32);
		Expect(33);
		str(table);
		Expect(8);
		str_list(columns);
		while (la->kind == 9) {
			Get();
			str_list(columns);
		}
		Expect(10);
		Expect(34);
		Expect(8);
		if (la->kind == 2) {
			strconst_list(values);
		} else if (la->kind == 3) {
			number_list(values);
		} else SynErr(42);
		while (la->kind == 9) {
			Get();
			if (la->kind == 2) {
				strconst_list(values);
			} else if (la->kind == 3) {
				number_list(values);
			} else SynErr(43);
		}
		Expect(10);
		Expect(5);
		if(errors->count==0){
		_insert(table,columns,values);flagg=1;}
}

void Parser::Update_command() {
		map<string,string> col_table;
		vector<string> a,b,c;int count=0;
		  string table;vector<int> condition; 
		Expect(29);
		str(table);
		Expect(30);
		key_value(col_table);
		while (la->kind == 1) {
			key_value(col_table);
		}
		if (la->kind == 28) {
			Get();
			Condition(condition,a,b,c,count);
		}
		Expect(5);
		if(errors->count==0){
		_update(table,col_table,condition,a,b,c);flagg=1;}
}

void Parser::Delete_command() {
		string table;vector<int> condition;int count=0;
		vector<string> a,b,c; 
		Expect(35);
		Expect(27);
		str(table);
		if (la->kind == 28) {
			Get();
			Condition(condition,a,b,c,count);
		}
		Expect(5);
		if(errors->count==0){
		_delete(table,condition,a,b,c);flagg=1;}
}

void Parser::Drop_command() {
		vector<string> tablelist;string table;
		Expect(22);
		str_list(tablelist);
		while (la->kind == 9) {
			Get();
			str_list(tablelist);
		}
		Expect(5);
		if(errors->count==0){
		_drop(tablelist);
			flagg=1;}
}

void Parser::str(string & xz) {
		Expect(1);
		xz.append(coco_string_create_char(t->val));
}

void Parser::Name_type_pair(vector<ckval> &a) {
		string name,typ,temp,temp2;ckval kv;
		kv.isdefault=false;
		kv.isindex=false;
		kv.isnull=true;
		str(name);
		type(typ);
		if (la->kind == 11 || la->kind == 12) {
			if (la->kind == 11) {
				Get();
				kv.isnull=true;	  
			} else {
				Get();
				Expect(11);
				kv.isnull=false;	  
			}
		}
		if (la->kind == 13) {
			Get();
			if (la->kind == 1) {
				str(temp2);
			} else if (la->kind == 3) {
				number(temp2);
			} else SynErr(44);
			kv.isdefault=true;
			kv.def=temp2;        
		}
		if (la->kind == 14) {
			Get();
			kv.isindex=true;      
		}
		kv.name=name;
		kv.type=typ;
		a.push_back(kv);
}

void Parser::type(string & type) {
		string num;
		switch (la->kind) {
		case 15: {
			Get();
			type.append("int");
			break;
		}
		case 16: {
			Get();
			type.append("float");
			break;
		}
		case 17: {
			Get();
			type.append("long");
			break;
		}
		case 18: {
			Get();
			type.append("date");
			break;
		}
		case 19: {
			Get();
			type.append("time");
			break;
		}
		case 20: {
			Get();
			number(num);
			type.append("char/");
			type.append(num);
			Expect(10);
			break;
		}
		case 21: {
			Get();
			number(num);
			type.append("varchar/");
			type.append(num);
			Expect(10);
			break;
		}
		default: SynErr(45); break;
		}
}

void Parser::number(string &a) {
		Expect(3);
		a.append(coco_string_create_char(t->val));
		
}

void Parser::str_list(vector<string> &list) {
		string temp;
		str(temp);
		list.push_back(temp);
}

void Parser::Condition(vector<int> &condition,vector<string> &a,vector<string> &b,vector<string> &c ,int &count) {
		int temp; 
		con(condition,a,b,c,count);
		while (la->kind == 36 || la->kind == 37) {
			if (la->kind == 36) {
				temp=-1;
				Get();
			} else {
				temp=-2;
				Get();
			}
			con(condition,a,b,c,count);
			condition.push_back(temp);
		}
}

void Parser::key_value(map<string,string> &col_table) {
		string table,key,value;
		str(key);
		Expect(31);
		if (la->kind == 3) {
			number(value);
		} else if (la->kind == 2) {
			strconst(value);
		} else SynErr(46);
		col_table.insert( make_pair( key,value)) ;
}

void Parser::strconst(string & xz) {
		Expect(2);
		string temp;
		temp.append(coco_string_create_char(t->val));
		xz.append(temp.substr(1,(strlen(temp.c_str())-2)));;
}

void Parser::strconst_list(vector<string> &list) {
		string temp;
		strconst(temp);
		list.push_back(temp);
}

void Parser::number_list(vector<string> &list) {
		string temp;
		number(temp);
		list.push_back(temp);
}

void Parser::con(vector<int> &x,vector<string> &a,vector<string> &b,vector<string> &c ,int &count) {
		if (la->kind == 8) {
			Get();
			Condition(x,a,b,c,count);
			Expect(10);
		} else if (la->kind == 1) {
			x.push_back(count);count++;
			str_list(a);
			r_list(b);
			if (la->kind == 3) {
				number_list(c);
			} else if (la->kind == 2) {
				strconst_list(c);
			} else SynErr(47);
		} else SynErr(48);
}

void Parser::r_list(vector<string> &list) {
		string temp;
		r(temp);
		list.push_back(temp);
}

void Parser::r(string &ab) {
		Expect(4);
		ab.append(coco_string_create_char(t->val));
}



void Parser::Parse() {
	t = NULL;
	la = dummyToken = new Token();
	la->val = coco_string_create(L"Dummy Token");
	Get();
	Sql();

	Expect(0);
}

Parser::Parser(Scanner *scanner) {
	maxT = 38;

	dummyToken = NULL;
	t = la = NULL;
	minErrDist = 2;
	errDist = minErrDist;
	this->scanner = scanner;
	errors = new Errors();
}

bool Parser::StartOf(int s) {
	const bool T = true;
	const bool x = false;

	static bool set[2][40] = {
		{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
		{x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,T,T, x,x,x,x, x,T,x,x, T,x,x,T, x,x,x,x}
	};



	return set[s][la->kind];
}

Parser::~Parser() {
	delete errors;
	delete dummyToken;
}

Errors::Errors() {
	count = 0;
}

void Errors::SynErr(int line, int col, int n) {
	wchar_t* s;
	switch (n) {
			case 0: s = coco_string_create(L"EOF expected"); break;
			case 1: s = coco_string_create(L"c expected"); break;
			case 2: s = coco_string_create(L"const expected"); break;
			case 3: s = coco_string_create(L"num expected"); break;
			case 4: s = coco_string_create(L"rel expected"); break;
			case 5: s = coco_string_create(L"\";\" expected"); break;
			case 6: s = coco_string_create(L"\"create\" expected"); break;
			case 7: s = coco_string_create(L"\"table\" expected"); break;
			case 8: s = coco_string_create(L"\"(\" expected"); break;
			case 9: s = coco_string_create(L"\",\" expected"); break;
			case 10: s = coco_string_create(L"\")\" expected"); break;
			case 11: s = coco_string_create(L"\"null\" expected"); break;
			case 12: s = coco_string_create(L"\"not\" expected"); break;
			case 13: s = coco_string_create(L"\"default\" expected"); break;
			case 14: s = coco_string_create(L"\"index\" expected"); break;
			case 15: s = coco_string_create(L"\"int\" expected"); break;
			case 16: s = coco_string_create(L"\"float\" expected"); break;
			case 17: s = coco_string_create(L"\"long\" expected"); break;
			case 18: s = coco_string_create(L"\"date\" expected"); break;
			case 19: s = coco_string_create(L"\"time\" expected"); break;
			case 20: s = coco_string_create(L"\"char(\" expected"); break;
			case 21: s = coco_string_create(L"\"varchar(\" expected"); break;
			case 22: s = coco_string_create(L"\"drop\" expected"); break;
			case 23: s = coco_string_create(L"\"select\" expected"); break;
			case 24: s = coco_string_create(L"\"distinct\" expected"); break;
			case 25: s = coco_string_create(L"\"all\" expected"); break;
			case 26: s = coco_string_create(L"\"*\" expected"); break;
			case 27: s = coco_string_create(L"\"from\" expected"); break;
			case 28: s = coco_string_create(L"\"where\" expected"); break;
			case 29: s = coco_string_create(L"\"update\" expected"); break;
			case 30: s = coco_string_create(L"\"set\" expected"); break;
			case 31: s = coco_string_create(L"\"=\" expected"); break;
			case 32: s = coco_string_create(L"\"insert\" expected"); break;
			case 33: s = coco_string_create(L"\"into\" expected"); break;
			case 34: s = coco_string_create(L"\"values\" expected"); break;
			case 35: s = coco_string_create(L"\"delete\" expected"); break;
			case 36: s = coco_string_create(L"\"and\" expected"); break;
			case 37: s = coco_string_create(L"\"or\" expected"); break;
			case 38: s = coco_string_create(L"??? expected"); break;
			case 39: s = coco_string_create(L"invalid Sql"); break;
			case 40: s = coco_string_create(L"invalid Modify_data"); break;
			case 41: s = coco_string_create(L"invalid Select_command"); break;
			case 42: s = coco_string_create(L"invalid Insert_command"); break;
			case 43: s = coco_string_create(L"invalid Insert_command"); break;
			case 44: s = coco_string_create(L"invalid Name_type_pair"); break;
			case 45: s = coco_string_create(L"invalid type"); break;
			case 46: s = coco_string_create(L"invalid key_value"); break;
			case 47: s = coco_string_create(L"invalid con"); break;
			case 48: s = coco_string_create(L"invalid con"); break;

		default:
		{
			wchar_t format[20];
			coco_swprintf(format, 20, L"error %d", n);
			s = coco_string_create(format);
		}
		break;
	}
	wprintf(L"-- line %d col %d: %ls\n", line, col, s);
	coco_string_delete(s);
	count++;
}

void Errors::Error(int line, int col, const wchar_t *s) {
	wprintf(L"-- line %d col %d: %ls\n", line, col, s);
	count++;
}

void Errors::Warning(int line, int col, const wchar_t *s) {
	wprintf(L"-- line %d col %d: %ls\n", line, col, s);
}

void Errors::Warning(const wchar_t *s) {
	wprintf(L"%ls\n", s);
}

void Errors::Exception(const wchar_t* s) {
	wprintf(L"%ls", s); 
	exit(1);
}



